package com.hy.hyaudio.opensles

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.hy.hyaudio.databinding.ActivityOpenslEsPlayerBinding
import com.hy.opensles.HYOpenSLESPlayer
import java.io.File
import java.io.FileInputStream
import java.util.concurrent.LinkedBlockingDeque
import java.util.concurrent.TimeUnit
import kotlin.concurrent.thread

/**
 * @Description:
 * @Author: wdk
 * @CreateTime: 2025/1/5 16:14
 */
class OpenSLESPlayerActivity : AppCompatActivity() {

    companion object {
        private const val TAG = "OpenSLESPlayerActivity"
    }

    private lateinit var binding: ActivityOpenslEsPlayerBinding
    var handler: Long = 0L
    private val openSLESPlayer: HYOpenSLESPlayer by lazy { HYOpenSLESPlayer() }

    private val deque = LinkedBlockingDeque<PcmData>()

    private var playing = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityOpenslEsPlayerBinding.inflate(layoutInflater)
        setContentView(binding.root)
        initListener()
        initData()
    }


    private fun initListener() {
        binding.initPlayOpenSLES.setOnClickListener {
            if (handler != 0L) {
                Toast.makeText(this, "资源已经初始化了", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            handler = openSLESPlayer.CreateInstance()
            Log.i(TAG, "CreateInstance: handler=$handler")
            if (handler != 0L) {
                val ret = openSLESPlayer.Init(handler)
                Log.i(TAG, "Init: ret=$ret")
            }
        }

        //播放pcm音频
        binding.startPlayOpenSLES.setOnClickListener {
            if (handler == 0L) {
                Toast.makeText(this, "请先初始化资源", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            if (playing) {
                Toast.makeText(this, "播放中，请先结束播放", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }


            playing = true
            play()
        }

        binding.stopPlayOpenSLES.setOnClickListener {
            if (handler == 0L) {
                Toast.makeText(this, "请先初始化资源", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            if (!playing) {
                Toast.makeText(this, "您还未开始播放", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            playing = false
            openSLESPlayer.release(handler)
            handler = 0L
        }

    }

    private fun initData() {
        thread {
            val pcmDirPath = "${filesDir.absolutePath}${File.separator}recorder"
            val dir = File(pcmDirPath)
            if (!dir.exists()) {
                dir.mkdirs()
            }
            val pcmFileList = dir.listFiles()
            if (pcmFileList.isNullOrEmpty()) {
                Log.e(TAG, "initData: pcmFileList is NULL")
                return@thread
            }

            val playFile = pcmFileList[pcmFileList.size - 1];
            Log.i(TAG, "initData: playFile=${playFile.absolutePath}")

            val inputStream = FileInputStream(playFile)

            var len = 0
            while (true) {
                val byteArray = ByteArray(44100 * 2 * 2)
                len = inputStream.read(byteArray)
                if (len == -1) {
                    break
                }

                val data = PcmData(byteArray, len)
                deque.add(data)
            }
            inputStream.close()
            Log.i(TAG, "loadData read done!  deque=${deque.size}")
        }
    }

    private fun play() {
        thread {
            while (playing && deque.size > 0) {
                try {
                    val data = deque.poll(100, TimeUnit.MILLISECONDS)
                    if (data == null) {
                        continue
                    }
                    openSLESPlayer.SendPcmData(handler, data.byteArray, data.size)

                } catch (e: Exception) {
                    e.printStackTrace()
                    Log.e(TAG, "openSlEsPlayer Exception ", e)
                }
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        playing = false
        deque.clear()
        if (handler != 0L) {
            openSLESPlayer.release(handler)
            handler = 0L
        }
    }

}